/**
  ******************************************************************************
  * @file    User/i2c1_paj7620.c
  * @date    04-Jul-2018
  * @brief   paj7620u2 config and get values functions
  ******************************************************************************
  */
  
#include "i2c1_bus.h"
#include "i2c1_paj7620.h"
#include "stdio.h"

void I2c1_Paj7620_Init(void)
{
	Paj7620_Int_Config();
	Paj7620_Init();
}

static void Paj7620_Int_Config(void)
{
	GPIO_InitTypeDef gpioInit;
	PAJ7620_INT_CLK_CMD(PAJ7620_INT_CLK, ENABLE);
	
	gpioInit.GPIO_Pin = PAJ7620_INT_PIN;
	gpioInit.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(PAJ7620_INT_PORT, &gpioInit);
}

uint8_t Paj7620_GetInterrupt(void)
{
	return GPIO_ReadInputDataBit(PAJ7620_INT_PORT, PAJ7620_INT_PIN) == 0;
	// Active low
}

static uint8_t Paj7620_Init(void)
{
	uint8_t data = 0, rtn = 0;
	uint16_t cnt = 0;
	
	delay_us(700);	//Wait 700us for PAJ7620U2 to stabilize
	Paj7620_SekectBank(PAJ7620_BANK0);
	rtn = I2C1_ReadData_8B_Addr(PAJ7620_ADDRESS, PAJ7620_ADDR_PART_ID_0, &data, 1);
	if(rtn)
	{
		return rtn;
	}
	if(data != PAJ7620_PART_ID_0)
	{
		return 0xff;
	}
	rtn = I2C1_ReadData_8B_Addr(PAJ7620_ADDRESS, PAJ7620_ADDR_PART_ID_1, &data, 1);
	if(rtn)
	{
		return rtn;
	}
	if(data != PAJ7620_PART_ID_1)
	{
		return 0xfe;
	}
	for (cnt = 0; cnt < INIT_REG_ARRAY_SIZE; cnt++) 
	{
		rtn = I2C1_WriteData(PAJ7620_ADDRESS, initRegisterArray[cnt][0], &initRegisterArray[cnt][1], 1);
		if(rtn)
		{
			return rtn;
		}
	}
	
	Paj7620_SekectBank(PAJ7620_BANK1);  //gesture flage reg in Bank1
	//data = 0xB7;	// far mode 120 fps
	data = 0x12;  		// near mode 240 fps
	I2C1_WriteData(PAJ7620_ADDRESS, 0x65, &data, 1); 

	Paj7620_SekectBank(PAJ7620_BANK0);  //gesture flage reg in Bank0
	
	return 0;
}

static uint8_t Paj7620_SekectBank(uint8_t bank)
{
	uint8_t rtn = 0;
	if(bank == PAJ7620_BANK0 || bank == PAJ7620_BANK1)
	{
		rtn = I2C1_WriteData(PAJ7620_ADDRESS, PAJ7620_REGITER_BANK_SEL, &bank, 1);
	}
	else
	{
		rtn = 0xff;
	}
	return rtn;
}

static uint16_t Paj7620_GetGesture(void)
{
	uint8_t rRtn = 0, rData[2] = {0};
	uint16_t gCode = 0;
	rRtn  = I2C1_ReadData_8B_Addr(PAJ7620_ADDRESS, PAJ7620_ADDR_GES_PS_DET_FLAG_0, rData, 2);
	if(rRtn)
	{
		return rRtn;
	}
	gCode = (rData[1]<<8) & 0xff00 | rData[0];
	return gCode;
}

void Paj7620_Action(void)
{
	uint16_t gCode = 0;
	gCode = Paj7620_GetGesture();
	printf("%d ", gCode);
	 switch (gCode) 
        {
		case 0x01: // up
			Paj7620_UpAction();
			break;
		case 0x02: // down
			Paj7620_DownAction();
			break;
		case 0x04: // left
			Paj7620_LeftAction();
			break;
		case 0x08: // right
			Paj7620_RightAction();
			break;
		case 0x10: // push
			Paj7620_PushAction();
			break;
		case 0x20: // pop
			Paj7620_PopAction();
			break;
		case 0x40: // rotate right
			Paj7620_RotateRightAction();
			break;
		case 0x80: // rotate left
			Paj7620_RotateLeftAction();
			break;
		case 0x100:// wave
			Paj7620_WaveAction();
			break;
		case 0x00: // nothing
			Paj7620_NothingAction();
		 	break;
		default:
			Paj7620_ErrorAction();
        }
}

static void Paj7620_UpAction(void)
{
	printf("up\r\n");
}

static void Paj7620_DownAction(void)
{
	printf("down\r\n");
}
static void Paj7620_LeftAction(void)
{
	printf("left\r\n");
}

static void Paj7620_RightAction(void)
{
	printf("right\r\n");
}

static void Paj7620_PushAction(void)
{
	printf("push\r\n");
}

static void Paj7620_PopAction(void)
{
	printf("pop\r\n");
}

static void Paj7620_RotateRightAction(void)
{
	printf("rotate right\r\n");
}

static void Paj7620_RotateLeftAction(void)
{
	printf("rotate left\r\n");
}

static void Paj7620_WaveAction(void)
{
	printf("wave\r\n");
}

static void Paj7620_NothingAction(void)
{
	printf("nothing\r\n");
}

static void Paj7620_ErrorAction(void)
{
	printf("error\r\n");
}
